/*************************************************************
 *************************************************************
 * EventHub.js
 * 
 * Handles inter-object communication of data and events, and
 * allow subscription to events.
 *************************************************************
 *************************************************************/

/**
 *
 * getObjectByName(name:String)
 *
 * Returns a reference to and object on the page.
 * Used to allow us to call a function on a SWF.
 *
 * @param name:String
 * @return void
 *
 */
 function getObjectByName(objectName)
 {
	if(window.document[objectName])
	{
		return window.document[objectName];
	}
	return document.getElementById(objectName);
 }

function EventHub()
{
	var _registeredObjects = {};
	var _registeredFunctions = [];
	var _listeners = {}; //Non-Javascript Listeners
	 
	/**
	 *
	 * dispatchEvent(event:Object)
	 *
	 * Dispatches an event to all subscribed components.
	 *
	 * @param event:Object
	 * @return void
	 */
	this.dispatchEvent = function(event)
	{
		for(var p in _listeners[event.type])
		{
			if(p != event.source)
			{
				getObjectByName(p).dispatchEvent(event);
			}
		}
		
		for(var p in _registeredFunctions[event.type])
		{
			_registeredFunctions[event.type][p](event);
		}
	};
	 
	 /**
	 *
	 * addSubscription(eventType:String, componentId:String)
	 *
	 * Called from within all SWFs that implement EventHub.as when
	 * the first child element adds a listener for an particular event.
	 * (So that only subscribed events are dispatched to a Component.)
	 *
	 * @param eventType:String
	 * @param componentId:String
	 * @return void
	 */
	this.addSubscription = function(eventType, componentId)
	{
		 if(!_listeners[eventType])
		 {
			_listeners[eventType] = {};
		 }
		_listeners[eventType][componentId] = true;
	};
	 
	/**
	 *
	 * removeSubscription(eventType:String, componentId:String)
	 *
	 * Called from within all SWFs that implement EventHub.as when
	 * the last child element unsubscribes for an particular event.
	 * (So that only subscribed events are dispatched to a Component.)
	 * 
	 * @param eventType:String
	 * @param componentId:String
	 * @return void
	 */
	this.removeSubscription = function(eventType, componentId)
	{
		delete _listeners[eventType][componentId];
	};
	 
	/**
	 *
	 * addEventListener(eventType:String, callbackFunction:Function)
	 *
	 * Subscribes a <code>callbackFunction</code> as a listener for
	 * <code>eventType</code>.
	 *
	 * @param eventType:String
	 * @param callbackFunction:Function
	 * @return void
	 */
	 this.addEventListener = function(eventType, callbackFunction)
	{
		for(var p in _registeredFunctions[eventType])
		{
			if(_registeredFunctions[eventType][p]) //if function is already registered for event
			{
				return;
			}
		}
		if(!_registeredFunctions[eventType]) //if no listeners for that event
		{
			_registeredFunctions[eventType] = [];
		}
		_registeredFunctions[eventType].push(callbackFunction);
	};
	 
	 /**
	 *
	 * removeEventListener(eventType:String, callbackFunction:Function)
	 *
	 * Unsubscribes <code>callbackFunction</code> as a listener for
	 * <code>eventType</code>.
	 *
	 * @param eventType:String
	 * @param callbackFunction:Function
	 * @return void
	 */
	 this.removeEventListener = function(eventType, callbackFunction)
	 {
		for(var p in _registeredFunctions[eventType])
		{
			if(_registeredFunctions[eventType][p])
			{
				delete _registeredFunctions[eventType][p];
			}
		}
	 };
};

var eventHub = new EventHub();
